﻿using AutoMapper;
using Domain.Material_Management;
using Domain.Production_Modules;
using Infratructure.Interface;
using MediatR;
using MES.Server.API.Application.Command.Production_Modules;
using ReturnValue;
using System.Transactions;
using Yitter.IdGenerator;

namespace MES.Server.API.Application.Handler.Production_Modules
{
    public class AddMaterialsInHander : IRequestHandler<AddMaterialInCommand, ApiResult<int>>
    {
        private readonly IRepository<MaterialOutInModel> materialOutInRepo;
        private readonly IMapper mapper;
        private readonly IRepository<ProductMaterialsModel> productMaterialsRepo;
        private readonly IRepository<MaterialAskModel> materialAskRepo;
        private readonly IRepository<MaterialInventoryModel> materialInventoryRepo;
        private readonly IRepository<MaterialOutAskModel> materialOutAskRepo;
        public AddMaterialsInHander(IRepository<MaterialOutInModel> materialOutInRepo, IMapper mapper, IRepository<ProductMaterialsModel> productMaterialsRepo, IRepository<MaterialAskModel> materialAskRepo, IRepository<MaterialInventoryModel> materialInventoryRepo, IRepository<MaterialOutAskModel> materialOutAskRepo)
        {
            this.materialOutInRepo = materialOutInRepo;
            this.mapper = mapper;
            this.productMaterialsRepo = productMaterialsRepo;
            this.materialAskRepo = materialAskRepo;
            this.materialInventoryRepo = materialInventoryRepo;
            this.materialOutAskRepo = materialOutAskRepo;
        }
        /// <summary>
        /// 物料入库
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<ApiResult<int>> Handle(AddMaterialInCommand request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<int>();
            var Inn = materialOutInRepo.GetAll().Where(x=>x.OutInCode==request.OutInCode).FirstOrDefault();
            if (Inn!=null)
            {
                result.Code = StatusCode.Fail;
                result.Message = "入库编码已存在,无法进行入库";
                return await Task.FromResult(result);
            }
            else
            {
                MaterialOutInModel MaterialIn = new MaterialOutInModel()
                {
                    OutInCode = request.OutInCode,
                    OutIn = OutInEnum.入库,
                    OutInCount = request.OutInCount,
                    ProductMaterialsId = request.ProductMaterialsId,
                    MaterialAskCode = request.MaterialAskCode,
                    CreaterPeople = request.CreaterPeople,
                    Id = YitIdHelper.NextId(),
                    CreateTime = DateTime.Now,
                    IsDel = false
                };
                if (MaterialIn.OutInCount < 1000)
                {
                    result.Code = StatusCode.Fail;
                    result.Message = "入库量少于1000,不满足入库条件";
                    return await Task.FromResult(result);
                }
                //当前入库的物料库存
                var materialInventory = materialInventoryRepo.GetAll().FirstOrDefault(x => x.ProductMaterialsId == request.ProductMaterialsId);
                materialInventory.CurrentInventory = materialInventory.CurrentInventory + (int)request.OutInCount;
                var materialOutAsk = materialOutAskRepo.GetAll().Where(x => x.OutAskCode == request.MaterialAskCode).FirstOrDefault();
                if (materialOutAsk != null)
                {
                    materialOutAsk.Status = 1;//已入库
                }
                int i1 = 0;
                int i2 = 0;
                int i3 = 0;
                using (TransactionScope tran = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        i1 = await materialOutInRepo.AddAsync(MaterialIn);
                        i2 = await materialInventoryRepo.UpdateAsync(materialInventory);
                        i3 = await materialOutAskRepo.UpdateAsync(materialOutAsk);
                        tran.Complete();
                    }
                    catch (Exception ex)
                    {

                        throw ex;
                    }
                }
                if (i1 > 0 && i2 > 0&&i3>0)
                {
                    result.Code = StatusCode.Success;
                    result.Message = "已成功入库";
                    return await Task.FromResult(result);
                }
                else
                {
                    result.Code = StatusCode.Fail;
                    result.Message = "入库失败";
                    return await Task.FromResult(result);
                }
            }
            
        }
    }
}
